﻿//============================================================================================
/*
 * @brief 有限状态机 - 状态条件。
 * 
 *********************************************************************************************/

using System;

namespace Imagine.Infrastructure.FiniteStateMachines
{
    /// <summary>
    /// 有限状态机 - 状态条件。
    /// </summary>
    public class FSMCondition
    {
        private Func<bool> _conditionHandle;

        protected FSMCondition() { }
        protected FSMCondition(Func<bool> handle) => BindCondition(handle);

        public static FSMCondition Create(Func<bool> handle = null) => handle != null ? new FSMCondition(handle) : new FSMCondition();

        public void BindCondition(Func<bool> handle) => _conditionHandle = handle;
        public virtual bool Condition() => _conditionHandle != null && _conditionHandle.Invoke();

        public static FSMCondition operator &(FSMCondition con1, FSMCondition con2) => new AndCondition(con1, con2);
        public static FSMCondition operator |(FSMCondition con1, FSMCondition con2) => new OrCondition(con1, con2);
        public static FSMCondition operator !(FSMCondition con) => new NotCondition(con);
    }

    /// <summary>
    /// 有限状态机 - “与”状态条件。
    /// </summary>
    public class AndCondition : FSMCondition
    {
        private readonly FSMCondition _condition1;
        private readonly FSMCondition _condition2;

        public AndCondition(FSMCondition con1, FSMCondition con2)
        {
            _condition1 = con1;
            _condition2 = con2;
        }

        public override bool Condition() => _condition1.Condition() && _condition2.Condition();
    }

    /// <summary>
    /// 有限状态机 - “非”状态条件。
    /// </summary>
    public class NotCondition : FSMCondition
    {
        private readonly FSMCondition _condition;

        public NotCondition(FSMCondition con)
        {
            _condition = con;
        }

        public override bool Condition()
        {
            return !_condition.Condition();
        }
    }

    /// <summary>
    /// 有限状态机 - “或”状态条件。
    /// </summary>
    public class OrCondition : FSMCondition
    {
        private readonly FSMCondition _condition1;
        private readonly FSMCondition _condition2;

        public OrCondition(FSMCondition con1, FSMCondition con2)
        {
            _condition1 = con1;
            _condition2 = con2;
        }

        public override bool Condition()
        {
            return _condition1.Condition() || _condition2.Condition();
        }
    }
}